home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / pmake / lst / RCS / lstConcat.c,v < prev    next >
Encoding:
Text File  |  1992-05-19  |  5.4 KB  |  175 lines

  1. head     1.6;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.6
  10. date     89.07.06.12.50.04;  author adam;  state Exp;
  11. branches ;
  12. next     ;
  13.  
  14.  
  15. desc
  16. @@
  17.  
  18.  
  19.  
  20. 1.6
  21. log
  22. @checked in with -k by kupfer at 92.05.18.17.32.34.
  23. @
  24. text
  25. @/*-
  26.  * listConcat.c --
  27.  *    Function to concatentate two lists.
  28.  *
  29.  * Copyright (c) 1988 by the Regents of the University of California
  30.  *
  31.  * Permission to use, copy, modify, and distribute this
  32.  * software and its documentation for any purpose and without
  33.  * fee is hereby granted, provided that the above copyright
  34.  * notice appears in all copies.  Neither the University of California nor
  35.  * Adam de Boor makes any representations about the suitability of this
  36.  * software for any purpose.  It is provided "as is" without
  37.  * express or implied warranty.
  38.  *
  39.  */
  40. #ifndef lint
  41. static char *rcsid =
  42. "$Id: lstConcat.c,v 1.6 89/07/06 12:50:04 adam Exp $ SPRITE (Berkeley)";
  43. #endif lint
  44.  
  45. #include    "lstInt.h"
  46.  
  47. /*-
  48.  *-----------------------------------------------------------------------
  49.  * Lst_Concat --
  50.  *    Concatenate two lists. New elements are created to hold the data
  51.  *    elements, if specified, but the elements themselves are not copied.
  52.  *    If the elements should be duplicated to avoid confusion with another
  53.  *    list, the Lst_Duplicate function should be called first.
  54.  *    If LST_CONCLINK is specified, the second list is destroyed since
  55.  *    its pointers have been corrupted and the list is no longer useable.
  56.  *
  57.  * Results:
  58.  *    SUCCESS if all went well. FAILURE otherwise.
  59.  *
  60.  * Side Effects:
  61.  *    New elements are created and appended the the first list.
  62.  *-----------------------------------------------------------------------
  63.  */
  64. ReturnStatus
  65. Lst_Concat (l1, l2, flags)
  66.     Lst              l1;     /* The list to which l2 is to be appended */
  67.     Lst              l2;     /* The list to append to l1 */
  68.     int                 flags;  /* LST_CONCNEW if LstNode's should be duplicated
  69.                  * LST_CONCLINK if should just be relinked */
  70. {
  71.     register ListNode      ln;     /* original LstNode */
  72.     register ListNode      nln;    /* new LstNode */
  73.     register ListNode      last;   /* the last element in the list. Keeps
  74.                  * bookkeeping until the end */
  75.     register List     list1 = (List)l1;
  76.     register List     list2 = (List)l2;
  77.  
  78.     if (!LstValid (l1) || !LstValid (l2)) {
  79.     return (FAILURE);
  80.     }
  81.  
  82.     if (flags == LST_CONCLINK) {
  83.     if (list2->firstPtr != NilListNode) {
  84.         /*
  85.          * We set the nextPtr of the
  86.          * last element of list two to be NIL to make the loop easier and
  87.          * so we don't need an extra case should the first list turn
  88.          * out to be non-circular -- the final element will already point
  89.          * to NIL space and the first element will be untouched if it
  90.          * existed before and will also point to NIL space if it didn't.
  91.          */
  92.         list2->lastPtr->nextPtr = NilListNode;
  93.         /*
  94.          * So long as the second list isn't empty, we just link the
  95.          * first element of the second list to the last element of the
  96.          * first list. If the first list isn't empty, we then link the
  97.          * last element of the list to the first element of the second list
  98.          * The last element of the second list, if it exists, then becomes
  99.          * the last element of the first list.
  100.          */
  101.         list2->firstPtr->prevPtr = list1->lastPtr;
  102.         if (list1->lastPtr != NilListNode) {
  103.          list1->lastPtr->nextPtr = list2->firstPtr;
  104.         }
  105.         list1->lastPtr = list2->lastPtr;
  106.     }
  107.     if (list1->isCirc && list1->firstPtr != NilListNode) {
  108.         /*
  109.          * If the first list is supposed to be circular and it is (now)
  110.          * non-empty, we must make sure it's circular by linking the
  111.          * first element to the last and vice versa
  112.          */
  113.         list1->firstPtr->prevPtr = list1->lastPtr;
  114.         list1->lastPtr->nextPtr = list1->firstPtr;
  115.     }
  116.     free ((Address)l2);
  117.     } else if (list2->firstPtr != NilListNode) {
  118.     /*
  119.      * We set the nextPtr of the last element of list 2 to be nil to make
  120.      * the loop less difficult. The loop simply goes through the entire
  121.      * second list creating new LstNodes and filling in the nextPtr, and
  122.      * prevPtr to fit into l1 and its datum field from the
  123.      * datum field of the corresponding element in l2. The 'last' node
  124.      * follows the last of the new nodes along until the entire l2 has
  125.      * been appended. Only then does the bookkeeping catch up with the
  126.      * changes. During the first iteration of the loop, if 'last' is nil,
  127.      * the first list must have been empty so the newly-created node is
  128.      * made the first node of the list.
  129.      */
  130.     list2->lastPtr->nextPtr = NilListNode;
  131.     for (last = list1->lastPtr, ln = list2->firstPtr;
  132.          ln != NilListNode;
  133.          ln = ln->nextPtr)
  134.     {
  135.         PAlloc (nln, ListNode);
  136.         nln->datum = ln->datum;
  137.         if (last != NilListNode) {
  138.         last->nextPtr = nln;
  139.         } else {
  140.         list1->firstPtr = nln;
  141.         }
  142.         nln->prevPtr = last;
  143.         nln->flags = nln->useCount = 0;
  144.         last = nln;
  145.     }
  146.  
  147.     /*
  148.      * Finish bookkeeping. The last new element becomes the last element
  149.      * of list one. 
  150.      */
  151.     list1->lastPtr = last;
  152.  
  153.     /*
  154.      * The circularity of both list one and list two must be corrected
  155.      * for -- list one because of the new nodes added to it; list two
  156.      * because of the alteration of list2->lastPtr's nextPtr to ease the
  157.      * above for loop.
  158.      */
  159.     if (list1->isCirc) {
  160.         list1->lastPtr->nextPtr = list1->firstPtr;
  161.         list1->firstPtr->prevPtr = list1->lastPtr;
  162.     } else {
  163.         last->nextPtr = NilListNode;
  164.     }
  165.  
  166.     if (list2->isCirc) {
  167.         list2->lastPtr->nextPtr = list2->firstPtr;
  168.     }
  169.     }
  170.  
  171.     return (SUCCESS);
  172. }
  173.     
  174. @
  175.